import { Injectable } from '@nestjs/common';
import { In, Repository } from 'typeorm';
import { Permission } from './entities/permission.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Request } from 'express';
import { UserService } from '../user/user.service';
import { User } from '../user/entities/user.entity';
import { RoleService } from '../role/role.service';
import { CreatePermissionDto } from './dto/permission.dto';

@Injectable()
export class PermissionService {
  constructor(
    @InjectRepository(Permission) private readonly permissionRepo: Repository<Permission>,
    private readonly userService: UserService,
    private readonly roleService: RoleService,
  ) {}

  /** 查询所有权限 */
  async findAllPermission(req: Request) {
    const user = req.user as User;
    // 用户角色信息
    const userRoleInfo = await this.userService.findByUserId(user.id);
    // 用户角色id
    const roleId = userRoleInfo.roles[0].id;
    // 当前角色所拥有的权限id
    const permissionIds = await this.roleService.findPermissionIdByRoleId(roleId);
    // 根据权限id查权限
    const permissions = await this.findPermissionByIds(permissionIds);
    // 构造父子级关系
    const permissionTree = this.buildPermissionTree(permissions);
    return permissionTree;
  }

  /** 根据id查询权限 */
  async findPermissionById(id: number) {
    return await this.permissionRepo.findOne({ where: { id } });
  }

  /** 根据权限所有权限id查询权限信息 */
  async findPermissionByIds(permissionIds: number[]) {
    return await this.permissionRepo.find({
      where: { id: In(permissionIds) },
      relations: { widgets: true },
      order: { id: 'ASC' },
    });
  }

  /** 创建权限（菜单） */
  createPermission(body: CreatePermissionDto) {
    return this.permissionRepo.save(body);
  }

  /** 构造permissionTree */
  buildPermissionTree(permissions: Permission[], parentId: number | null = null) {
    const permissionTree: Permission[] = [];

    permissions.forEach((item) => {
      if (item.parentId === parentId) {
        const children = this.buildPermissionTree(permissions, item.id);
        if (children.length) {
          item.children = children;
        }
        permissionTree.push(item);
      }
    });

    return permissionTree;
  }
}
